from PySide6.QtWidgets import QLabel, QHBoxLayout, QCheckBox, QLineEdit, QPushButton, QFileDialog, QHBoxLayout,\
                              QMenu, QToolButton, QApplication
from PySide6.QtCore import Qt, Slot, QTimer, Slot, QPropertyAnimation, QSettings, QDir, QFileInfo
from PySide6.QtGui import QCursor


def checkbox_ui(label_text: str, txt_tuple: tuple, checked_index: int = 0):
    box_list = []
    layout = QHBoxLayout()
    label = QLabel(f'{label_text}')
    label.setFixedWidth(90)
    label.setAlignment(Qt.AlignCenter)
    layout.addWidget(label)
    for txt in txt_tuple:
        checkbox = QCheckBox(txt)
        layout.addWidget(checkbox)
        box_list.append(checkbox)
    box_list[checked_index].setChecked(True)
    return layout, box_list


class SelectButton(QToolButton):
    BUTTON_STYLE = """
            QToolButton {
                padding: 2px 5px;
                background: #ffffff;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
            QToolButton:hover {
                background: #e0e0e0;
            }
            QToolButton:!hover {      /* 新增非悬停状态 */
                background: #ffffff;  /* 确保离开后恢复白色 */
            }
            /* 强制隐藏箭头 */
            QToolButton::menu-indicator {
                image: none;
            }
        """
    
    MENU_STYLE = """
            QMenu {
                background-color: #ffffff;
                border: 1px solid #ccc;
                padding: 0px;  /* 移除内边距 */
                margin: 0px;   /* 移除外边距 */
            }
            QMenu::item {
                padding: 5px 5px;  /* 调整菜单项的内边距 */
                background-color: transparent;
            }
            QMenu::item:selected {
                background-color: #e0e0e0;
            }
            QMenu::separator {
                height: 0px;  /* 移除分隔线 */
            }
        """
    
    def __init__(self, file_path_edit: QLineEdit = None, file_type: str = 'All Files(*.)', dir_path_edit: QLineEdit = None):
        super().__init__()
        self._menu = QMenu(self)
        self._hide_timer = QTimer()
        self.file_path_edit = file_path_edit
        self.file_type = file_type
        self.dir_path_edit = dir_path_edit
        self.initUI()
        self.settings = QSettings("MyCompany", "MyApp")

    def initUI(self):
        if self.dir_path_edit:  # 如果需要同时支持文件和文件夹选择
            # 配置菜单
            self._menu.addAction("📄 选择文件", lambda: self.open_file(self.file_type, self.file_path_edit))
            self._menu.addAction("📁 选择文件夹", lambda: self.open_directory(self.dir_path_edit))
            
            # 按钮设置
            self.setPopupMode(QToolButton.InstantPopup)  # 设置为即时弹出模式
            self.setMenu(self._menu)
            # 菜单样式设置
            self._menu.setStyleSheet(self.MENU_STYLE)
            
            # 配置定时器
            self._hide_timer.setSingleShot(True)
            self._hide_timer.timeout.connect(self._check_hide)
        else:  # 如果只需要文件选择功能
            self.clicked.connect(lambda: self.open_file(self.file_type, self.file_path_edit))
        
        # 通用按钮设置
        self.setText("选择")
        self.setArrowType(Qt.NoArrow)
        self.setStyleSheet(self.BUTTON_STYLE)
        
    def enterEvent(self, event):
        """鼠标进入时立即显示菜单"""
        if self.dir_path_edit:  # 只在有菜单时显示
            self.showMenu()
            self._hide_timer.stop()

    def leaveEvent(self, event):
        """鼠标离开时启动隐藏检测"""
        if self.dir_path_edit:  # 只在有菜单时处理
            self._hide_timer.start(200)

    def showEvent(self, event):
        # 添加菜单显示动画
        animation = QPropertyAnimation(self._menu, b"windowOpacity")
        animation.setDuration(150)
        animation.setStartValue(0)
        animation.setEndValue(1)
        animation.start()

    def _check_hide(self):
        """智能隐藏检测"""
        # 获取当前鼠标所在的控件
        widget = QApplication.widgetAt(QCursor.pos())
        
        # 如果鼠标不在按钮或菜单区域则隐藏
        if widget not in [self, self._menu]:
            self._menu.hide()

    def open_file(self, file_type: str, edit: QLineEdit):
        """打开文件对话框"""
        last_dir = self.settings.value("last_dir", QDir.homePath())    # 获取上次保存的目录，不存在时返回用户主目录
        file_path, _ = QFileDialog.getOpenFileName(self, "选择文件", last_dir, file_type)
        
        if file_path:
            self.settings.setValue("last_dir", QFileInfo(file_path).dir().absolutePath())        # 保存目录路径到设置
            edit.setText(file_path)

    def open_directory(self, edit: QLineEdit):
        """打开目录对话框"""
        last_dir = self.settings.value("last_dir", QDir.homePath())    # 获取上次保存的目录，不存在时返回用户主目录
        dir_path = QFileDialog.getExistingDirectory(self, "选择文件夹", last_dir)
        
        if dir_path:
            self.settings.setValue("last_dir", dir_path)
            edit.setText(dir_path)


def file_path_ui(file_name: str, need_select_dir: bool = True):
    layout = QHBoxLayout()
    path_label = QLabel(file_name)
    path_label.setFixedWidth(120)
    path_label.setAlignment(Qt.AlignCenter)
    path_edit = QLineEdit()
    path_edit.setReadOnly(True)
    path_edit.setAlignment(Qt.AlignLeft)
    path_edit.setToolTip(f'请选择{file_name}')
    if need_select_dir:
        path_btn = SelectButton(path_edit, 'Excel Files (*.xlsx)', path_edit)
    else:
        path_btn = SelectButton(path_edit, 'Excel Files (*.xlsx)')
    # path_btn.clicked.connect(lambda: self.file(path_edit))     # 不能在这里绑定，不然后面的实例会覆盖掉前面的实例
    layout.addWidget(path_label)
    layout.addWidget(path_edit)
    layout.addWidget(path_btn)
    return layout, path_label, path_edit, path_btn

class SelectButton(QToolButton):
    BUTTON_STYLE = """
            QToolButton {
                padding: 2px 5px;
                background: #ffffff;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
            QToolButton:hover {
                background: #e0e0e0;
            }
            QToolButton:!hover {      /* 新增非悬停状态 */
                background: #ffffff;  /* 确保离开后恢复白色 */
            }
            /* 强制隐藏箭头 */
            QToolButton::menu-indicator {
                image: none;
            }
        """
    
    MENU_STYLE = """
            QMenu {
                background-color: #ffffff;
                border: 1px solid #ccc;
                padding: 0px;  /* 移除内边距 */
                margin: 0px;   /* 移除外边距 */
            }
            QMenu::item {
                padding: 5px 5px;  /* 调整菜单项的内边距 */
                background-color: transparent;
            }
            QMenu::item:selected {
                background-color: #e0e0e0;
            }
            QMenu::separator {
                height: 0px;  /* 移除分隔线 */
            }
        """
    
    def __init__(self, file_path_edit: QLineEdit = None, file_type: str = 'All Files(*.)', dir_path_edit: QLineEdit = None):
        super().__init__()
        self._menu = QMenu(self)
        self._hide_timer = QTimer()
        self.file_path_edit = file_path_edit
        self.file_type = file_type
        self.dir_path_edit = dir_path_edit
        self.initUI()
        self.settings = QSettings("MyCompany", "MyApp")

    def initUI(self):
        if self.dir_path_edit:  # 如果需要同时支持文件和文件夹选择
            # 配置菜单
            self._menu.addAction("📄 选择文件", lambda: self.open_file(self.file_type, self.file_path_edit))
            self._menu.addAction("📁 选择文件夹", lambda: self.open_directory(self.dir_path_edit))
            
            # 按钮设置
            self.setPopupMode(QToolButton.InstantPopup)  # 设置为即时弹出模式
            self.setMenu(self._menu)
            # 菜单样式设置
            self._menu.setStyleSheet(self.MENU_STYLE)
            
            # 配置定时器
            self._hide_timer.setSingleShot(True)
            self._hide_timer.timeout.connect(self._check_hide)
        else:  # 如果只需要文件选择功能
            self.clicked.connect(lambda: self.open_file(self.file_type, self.file_path_edit))
        
        # 通用按钮设置
        self.setText("选择")
        self.setArrowType(Qt.NoArrow)
        self.setStyleSheet(self.BUTTON_STYLE)
        
    def enterEvent(self, event):
        """鼠标进入时立即显示菜单"""
        if self.dir_path_edit:  # 只在有菜单时显示
            self.showMenu()
            self._hide_timer.stop()

    def leaveEvent(self, event):
        """鼠标离开时启动隐藏检测"""
        if self.dir_path_edit:  # 只在有菜单时处理
            self._hide_timer.start(200)

    def showEvent(self, event):
        # 添加菜单显示动画
        animation = QPropertyAnimation(self._menu, b"windowOpacity")
        animation.setDuration(150)
        animation.setStartValue(0)
        animation.setEndValue(1)
        animation.start()

    def _check_hide(self):
        """智能隐藏检测"""
        # 获取当前鼠标所在的控件
        widget = QApplication.widgetAt(QCursor.pos())
        
        # 如果鼠标不在按钮或菜单区域则隐藏
        if widget not in [self, self._menu]:
            self._menu.hide()

    def open_file(self, file_type: str, edit: QLineEdit):
        """打开文件对话框"""
        last_dir = self.settings.value("last_dir", QDir.homePath())    # 获取上次保存的目录，不存在时返回用户主目录
        file_path, _ = QFileDialog.getOpenFileNames(self, "选择文件", last_dir, file_type)
        
        if file_path:
            self.settings.setValue("last_dir", QFileInfo(file_path[0]).dir().absolutePath())        # 保存目录路径到设置
            edit.setText(', '.join(file_path))

    def open_directory(self, edit: QLineEdit):
        """打开目录对话框"""
        last_dir = self.settings.value("last_dir", QDir.homePath())    # 获取上次保存的目录，不存在时返回用户主目录
        dir_path = QFileDialog.getExistingDirectory(self, "选择文件夹", last_dir)
        
        if dir_path:
            self.settings.setValue("last_dir", dir_path)
            edit.setText(dir_path)
